/*
 Problem Description
“连连看”相信很多人都玩过。没玩过也没关系，下面我给大家介绍一下游戏规则：在一个棋盘中，放了很多的棋子。如果某两个相同的棋子，可以通过一条线连起来（这条线不能经过其它棋子），而且线的转折次数不超过两次，那么这两个棋子就可以在棋盘上消去。不好意思，由于我以前没有玩过连连看，咨询了同学的意见，连线不能从外面绕过去的，但事实上这是错的。现在已经酿成大祸，就只能将错就错了，连线不能从外围绕过。
玩家鼠标先后点击两块棋子，试图将他们消去，然后游戏的后台判断这两个方格能不能消去。现在你的任务就是写这个后台程序。
Input
输入数据有多组。每组数据的第一行有两个正整数n,m(0<n<=1000,0<m<1000)，分别表示棋盘的行数与列数。
在接下来的n行中，每行有m个非负整数描述棋盘的方格分布。0表示这个位置没有棋子，正整数表示棋子的类型。
接下来的一行是一个正整数q(0<q<50)，表示下面有q次询问。在接下来的q行里，每行有四个正整数x1,y1,x2,y2,表示询问第x1行y1列的棋子与第x2行y2列的棋子能不能消去。n=0,m=0时，输入结束。
注意：询问之间无先后关系，都是针对当前状态的！
Output
每一组输入数据对应一行输出。如果能消去则输出"YES",不能则输出"NO"。
Sample Input
3 4
1 2 3 4
0 0 0 0
4 3 2 1
4
1 1 3 4
1 1 2 4
1 1 3 3
2 1 2 4
3 4
0 1 4 3
0 2 4 1
0 0 0 0
2
1 1 2 4
1 3 2 3
0 0
Sample Output
YES
NO
NO
NO
NO
YES
 */
package com.yuan.algorithms.practice201505;

import java.io.BufferedInputStream;
import java.util.Scanner;

public class 连连看 {

	static int[][] map;
	static int x1,y1,x2,y2;
	static boolean result;
	static Scanner sc = new Scanner(new BufferedInputStream(System.in));
	public static void main(String[] args) {
		while(sc.hasNext()) {
			int n = sc.nextInt();
			int m = sc.nextInt();
			if (n==0&&m==0) {
				break;
			}
			map = new int[n][m];
			result = false;
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					map[i][j] = sc.nextInt();					
				}				
			}
			int k = sc.nextInt();
			for (int i = 0; i < k; i++) {
				x1 = sc.nextInt()-1;
				y1 = sc.nextInt()-1;
				x2 = sc.nextInt()-1;
				y2 = sc.nextInt()-1;
				result = false;
				if (map[x1][y1]==map[x2][y2] && (map[x1][y1]!=0 || map[x2][y2]!=0)) {
					dfs(x1,y1,0,0,-1);
				}
				if (result) {
					System.out.println("YES");
				}else {
					System.out.println("NO");
				}
			}
		}
	}
	
	/**
	 * 
	 * @param x 当前x坐标
	 * @param y 当前y坐标
	 * @param i 上一次方向
	 * @param j 当前方向
	 * @param k 拐弯次数
	 */
	private static void dfs(int x, int y, int i, int j, int k) {
		if (result) {//找到答案，快速返回
			return;
		}
		if (x<0||y<0||x>=map.length||y>=map[0].length) {
			return;
		}
		if (i!=j) {//方向不同，拐弯数+1
			k++;
		}
		if (k>2) {//剪枝：如果转弯次数超过两次，return
			return;
		}
		//剪枝：如果转弯次数达到两次，和目标并不在一直线上 return;
		if (k == 2 && (x != x2 && y != y2)) {
			return;
		}
		if (x==x2&&y==y2) {
			result = true;
			return;
		}
		if (map[x][y]!=0 && k!=-1) {
			return;
		}
		dfs(x-1, y, j, 1, k);//上
		dfs(x, y+1, j, 2, k);//右
		dfs(x+1, y, j, 3, k);//下
		dfs(x, y-1, j, 4, k);//左		
	}
}
